/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package orgarqsindex;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 *
 * @author Fernando Molon Toigo e Dyoni Bertuol
 */
public class PrimaryKeyIndexFileGenerator {

    private File sourceFile;
    private File targetFile;
    private int rowSize;
    private int primaryKeyBeginIndex;
    private int primaryKeySize;
    private int indexRowSize;

    public PrimaryKeyIndexFileGenerator(File sourceFile, File targetFile, int rowSize, int primaryKeyBeginIndex, int primaryKeySize) {
        this.sourceFile = sourceFile;
        this.targetFile = targetFile;
        this.rowSize = rowSize;
        this.primaryKeyBeginIndex = primaryKeyBeginIndex;
        this.primaryKeySize = primaryKeySize;
        indexRowSize = primaryKeySize + String.valueOf(sourceFile.length() / rowSize).length() + 2; //2 - pulagem de linha
    }

    public void generate() throws FileNotFoundException, IOException {
        if (targetFile.exists()) {
            targetFile.delete();
        }

        RandomAccessFile sraf = new RandomAccessFile(sourceFile, "r");
        RandomAccessFile traf = new RandomAccessFile(targetFile, "rw");

        byte[] buffer = new byte[primaryKeySize];

        for (long i = 0; i < sourceFile.length(); i += rowSize) {
        //for (long i = 0; i < 10000 * rowSize; i += rowSize) {
            sraf.seek(i + primaryKeyBeginIndex);
            sraf.read(buffer);
            //System.out.println(i/rowSize);
            insertIntoTarget(traf, buffer, i);
        }

        sraf.close();
        traf.close();
    }

    private void insertIntoTarget(RandomAccessFile traf, byte[] data, long sourcePosition) throws IOException {
        String stringData = new String(data, "ISO-8859-1");
        long start = 0;
        long end = traf.length();

        long middle = 0;
        byte[] buffer = new byte[primaryKeySize];
        boolean found = false;
        while (start != end && !found) {

            middle = ((start + end) / 2);
            middle = (middle / indexRowSize) * indexRowSize;

            traf.seek(middle + primaryKeyBeginIndex);
            traf.read(buffer);

            String readData = new String(buffer, "ISO-8859-1");

            if (readData.compareToIgnoreCase(stringData) > 0) {
                end = middle;
            } else if (readData.compareToIgnoreCase(stringData) < 0) {
                start = middle + indexRowSize;
            } else {
                found = true;
            }
        }

        //expand file moment
        if (start == end) {
            middle = start;
        }

        long i = traf.length();

        //deslocamento
        int bufferLeftSize = Integer.valueOf(String.valueOf(i - middle));
        if (bufferLeftSize > 0) {
            buffer = new byte[bufferLeftSize];
            traf.seek(middle);
            traf.read(buffer);
            traf.seek(middle + indexRowSize);
            traf.write(buffer);
        }

        traf.seek(middle);
        traf.writeBytes(stringData + String.format("%0" + String.valueOf(sourceFile.length() / rowSize).length() + "d", sourcePosition / rowSize) + "\r\n");
    }
}
